package com.baohua.service.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.baohua.dao.InStoreDao;
import com.baohua.exception.BaohuaSystemException;
import com.baohua.model.InStore;
import com.baohua.model.Inventory;
import com.baohua.model.Staff;
import com.baohua.service.InStoreService;
import com.baohua.service.InventoryService;
import com.baohua.service.StaffService;
import com.baohua.util.ExcelUtil;

@Service("instoreService")
public class InStoreServiceImpl implements InStoreService {

	/**
	 * 增加采购/领料单数据
	 * @param status   出库/入库状态
	 * @param inStoreNO  采购单号/领料单号
	 * @param warehousingDate 出库/入库时间
	 * @param staffNO 经办人编号
	 * @param memo 备注说明
	 * @param arr_no 采购明细/领料明细中的物料编码所组成的字符串, eg：1, 2, 3
	 * @param arr_amount 采购明细/领料明细中数量所组成的字符串, eg：1, 2, 3
	 * @throws ParseException
	 * @throws BaohuaSystemException
	 */
	@Override
	public void addInStore(String status, String inStoreNO,
			String warehousingDate, String staffNO, String memo, String arr_no,
			String arr_amount) throws ParseException, BaohuaSystemException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = sdf.parse(warehousingDate);
		
		Staff staff = staffService.queryStaffByStaffNo(staffNO);
		
		String[] inventoryNOs = arr_no.split(",");
		String[] amounts = arr_amount.split(",");
		//判断传过来的值是否为空, 为空时, 返回错误信息
			for(int i=0; i< inventoryNOs.length;i++) {
				Inventory inventory = inventoryService.getInventoryByNO(inventoryNOs[i]);
				InStore in  = new InStore();
				//对出库/入库设值,保存数据
					in.setInStoreNO(inStoreNO);
					in.setRawMaterialName(inventory.getInventoryName());
					in.setRawMaterialNo(inventory.getInventoryNO());
					in.setStatus(status);
					in.setMemo(memo);
					in.setUnit(inventory.getUnit());
					in.setUnitPrice(inventory.getUnitPrice());
					in.setWarehousingAmount(Double.parseDouble(amounts[i]));
					in.setWarehousingDate(date);
					in.setPriceAmount(inventory.getUnitPrice()*Double.parseDouble(amounts[i]));
					in.setStaff(staff);
				    instoreDao.addInStore(in);
				
				//如果状态为入库时, 库存表中要进行相应修改    
				if(StringUtils.equals(status, "0")) {
					//设置初期库存
					inventory.setPreviousMonthStockAmount(inventory.getInventoryAmount());
					//设置最新入库数量
					inventory.setWarehousingAmount(Double.parseDouble(amounts[i]));
					//入库成功, 应加数据加入库存中
					double inventoryAmount = inventory.getInventoryAmount() + Double.parseDouble(amounts[i]);
					//设置当前库存
					inventory.setInventoryAmount(inventoryAmount);
					//重新计算金额
					inventory.setPriceAmount(inventoryAmount * inventory.getUnitPrice());
					inventoryService.updateInventory(inventory);
				}
				
				//如果状态为出库时, 库存表中要进行相应修改    
				if(StringUtils.equals(status, "1")) {
					if(inventory.getInventoryAmount()!=0) {
					//设置初期库存
					inventory.setPreviousMonthStockAmount(inventory.getInventoryAmount());
					//设置最新出库数量
					inventory.setDeliveryAmount(Double.parseDouble(amounts[i]));
					double inventoryAmount = inventory.getInventoryAmount() - Double.parseDouble(amounts[i]);
					inventory.setInventoryAmount(inventoryAmount);
					inventory.setPriceAmount(inventoryAmount * inventory.getUnitPrice());
					inventoryService.updateInventory(inventory);
					}else {
						throw new BaohuaSystemException("库存为空, 不能出库!");
					}
				}
			}
		
	}
	
	 /**
	  * 根据出库/入库ID进行删除
	  * @param id
	  * @throws BaohuaSystemException
	  */
	@Override
	public void deleteInStore(int id) throws BaohuaSystemException {
		
	}

	 /**
	  * 根据条件查询出库/入库数据
	  * @param instore  出库/入库对象
	  * @param pre_warehousingDate 前置出库/入库日期
	  * @param af_warehousingDate 后置出库/入库日期
	  * @param pre_warehousingAmount 前置总额
	  * @param af_warehousingAmount 后置总额
	  * @param status  出库/入库状态
	  * @param staffNO 员工编号
	  * @param page  
	  * @param pagesize
	  * @return
	  * @throws ParseException
	  */
	@SuppressWarnings("unchecked")
	public Map queryInStore(InStore instore, String pre_warehousingDate, String af_warehousingDate,
			 String pre_warehousingAmount, String af_warehousingAmount, 
			 String status, String staffNO, int page, int pagesize) throws ParseException{
		Map map = new HashMap();
		//拼接查询语句
		StringBuffer sqlCount = new StringBuffer("select count(*) from InStore s where status = " + status);
		StringBuffer sql = new StringBuffer("from InStore s where status = " + status);
		if(!StringUtils.isEmpty(instore.getInStoreNO())) {
			sql.append(" and s.inStoreNO = '" + instore.getInStoreNO() + "'");
			sqlCount.append(" and s.inStoreNO = '" + instore.getInStoreNO() + "'");
		}
		if(!StringUtils.isEmpty(instore.getRawMaterialName())) {
			sql.append(" and s.rawMaterialName = '" + instore.getRawMaterialName() + "'");
			sqlCount.append(" and s.rawMaterialName = '" + instore.getRawMaterialName() + "'");
		}
		
		if(!StringUtils.isEmpty(instore.getRawMaterialNo())) {
			sql.append(" and s.rawMaterialNo = '" + instore.getRawMaterialNo() + "'");
			sqlCount.append(" and s.rawMaterialNo = '" + instore.getRawMaterialNo() + "'");
		}
		
		if(!StringUtils.isEmpty(pre_warehousingDate)) {
			sql.append(" and s.warehousingDate >= '" + pre_warehousingDate + "'");
			sqlCount.append(" and s.warehousingDate >= '" + pre_warehousingDate + "'");
		}
		
		if(!StringUtils.isEmpty(af_warehousingDate)) {
			sql.append(" and s.warehousingDate <= '" + af_warehousingDate + "'");
			sqlCount.append(" and s.warehousingDate <= '" + af_warehousingDate + "'");
		}
		
		if(!StringUtils.isEmpty(pre_warehousingAmount)) {
			sql.append(" and s.warehousingAmount >= '" + pre_warehousingAmount + "'");
			sqlCount.append(" and s.warehousingAmount >= '" + pre_warehousingAmount + "'");
		}
		
		if(!StringUtils.isEmpty(af_warehousingAmount)) {
			sql.append(" and s.warehousingAmount <= '" + af_warehousingAmount + "'");
			sqlCount.append(" and s.warehousingAmount <= '" + af_warehousingAmount + "'");
		}
		
		if(!StringUtils.isEmpty(staffNO)) {
			sql.append(" and s.staff.staffNO >= '" + staffNO + "'");
			sqlCount.append(" and s.staff.staffNO >= '" + staffNO + "'");
		}
		
		List<InStore> list = instoreDao.queryInStore(sql.toString(),(page-1)*pagesize, pagesize);
		long count = instoreDao.countInStore(sqlCount.toString());
		map.put("Rows", list);
		map.put("Total", count);
		
		return map;
	}
	
	/**
	 * 根据出库/入库Id的数组, 查询出入库列表
	 * @param instoreIds
	 * @return
	 */
	public List<InStore> queryByInstoreIds(String[] instoreIdstrs){
		 Integer[] instoreIds =  new Integer[instoreIdstrs.length];
		  for(int i=0; i<instoreIds.length; i++) {
			  instoreIds[i] = Integer.parseInt(instoreIdstrs[i]); 
		  }
		List<InStore> list = new ArrayList<InStore>();
		if(instoreIds.length!=0) {
		  list = instoreDao.queryByInstoreIds(instoreIds);
		}
		return list;
	}

	/**
	 * 导出数据/模板
	 * @param output 缓存输出流
	 * @param file 导出文件
	 * @param list 导出数据
	 * @param sheetName 工作薄的名字
	 * @param HttpServletRequest request Request对象
	 * @param HttpServletResponse response Response对象
	 * @throws IllegalArgumentException
	 * @throws IOException
	 * @throws IllegalAccessException
	 */
	public void exportData(String fileName, List list, String sheetName,
			 HttpServletRequest request, HttpServletResponse response)
					 throws IllegalArgumentException, 
			 IOException, IllegalAccessException {
		InputStream bis = null;
		OutputStream bos = null;
		OutputStream output = null;
		ExcelUtil<InStore> excelUtil = new ExcelUtil<InStore>(InStore.class);
		File file = new File(fileName);
		response.setContentType("application/x-msdownload;"); 
		output = new BufferedOutputStream(new FileOutputStream(file));
		if(list.size()==0) {
			excelUtil.exportExcel(list, sheetName, true, output);
		}else {
			excelUtil.exportExcel(list, sheetName, false, output);
		}
		 
		String agent = request.getHeader("USER-AGENT");
		if (null != agent && -1 != agent.indexOf("MSIE")){//IE
		// 设置文件头，文件名称或编码格式
		   response.setHeader("Content-Disposition", "attachment;filename="
		           + java.net.URLEncoder.encode(file.getName(), "UTF-8"));
		}else{//firefox
			response.setHeader("Content-disposition", "attachment; filename="  
	                + new String(file.getName().getBytes("utf-8"), "ISO8859-1"));
		}
      response.setHeader("Content-Length", String.valueOf(file.length()));
		
			bis = new BufferedInputStream(new FileInputStream(file));  
          bos = new BufferedOutputStream(response.getOutputStream());  
          byte[] buff = new byte[2048];  
          int bytesRead;  
          while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {  
              bos.write(buff, 0, bytesRead); 
          }
          if (bis != null)
				bis.close();
			if (bos != null)
				bos.close();
	}
	
	 /**
	  * 根据出库/入库Id查询数据
	  * @param id
	  * @return
	  */
	@Override
	public InStore queryInStoreById(int id) {
		return instoreDao.queryInStoreById(id);
	}
	
	
	
	private InStoreDao instoreDao;
    private InventoryService inventoryService;
    private StaffService staffService;
    
	public InventoryService getInventoryService() {
		return inventoryService;
	}

	@Resource(name="inventoryService")
	public void setInventoryService(InventoryService inventoryService) {
		this.inventoryService = inventoryService;
	}

	public StaffService getStaffService() {
		return staffService;
	}

	@Resource(name="staffService")
	public void setStaffService(StaffService staffService) {
		this.staffService = staffService;
	}

	public InStoreDao getInstoreDao() {
		return instoreDao;
	}

	@Resource(name="instoreDao")
	public void setInstoreDao(InStoreDao instoreDao) {
		this.instoreDao = instoreDao;
	}

}
